package com.zzm.validate.web;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import com.zzm.validate.web.injector.ArgInjectorFactory;

/**
 * 验证框架的配置类 用于初始化配置，创建FormValidator
 */
public class ValidateConfig {

	private static final String VALIDATORS_XML = "com/zzm/validate/validator/validators.xml";
	private static final String DEFAULT_BUNDLE = "validate";
	private static final String DEFAULT_CONFIG = "validate.xml";
	private static final String FORM_VALIDATOR = "FormValidator";

	private boolean useDefaultValidators = true;
	private boolean useDefaultConfigName = true;
	private String bundle = DEFAULT_BUNDLE;
	private Locale locale = Locale.getDefault();
	private List<InputStream> configFiles = new ArrayList<InputStream>();

	public ValidateConfig useDefaultValidators(boolean use) {
		this.useDefaultValidators = use;
		return this;
	}

	public ValidateConfig setBundle(String bundle) {
		this.bundle = bundle;
		return this;
	}

	public ValidateConfig setBundle(String bundle, Locale locale) {
		this.setBundle(bundle);
		this.locale = locale;
		return this;
	}

	public ValidateConfig addConfigFile(String configFilePath) {
		if(!configFilePath.equals(DEFAULT_CONFIG) && 
		   !configFilePath.equals(VALIDATORS_XML)) {
			this.useDefaultConfigName = false;
		}
		this.configFiles.add(getClassPathResourceAsStream(configFilePath));
		return this;
	}

	public ValidateConfig addConfigFile(String[] configFilePaths) {
		for (String path : configFilePaths) {
			this.addConfigFile(path);
		}
		return this;
	}

	private InputStream getClassPathResourceAsStream(String path) {
		return this.getClass().getClassLoader().getResourceAsStream(path);
	}

	public FormValidator buildFormValidator() throws Exception {
		if (useDefaultValidators) {
			this.addConfigFile(VALIDATORS_XML);
		}
		if(useDefaultConfigName) {
			this.addConfigFile(DEFAULT_CONFIG);
		}
		ArgInjectorFactory argInjectorFactory = new ArgInjectorFactory();
		InputStream[] streams = new InputStream[this.configFiles.size()];
		for (int i = 0; i < streams.length; i++) {
			streams[i] = this.configFiles.get(i);
		}
		WebValidateResources validatorResources = new WebValidateResources(
				streams);
		ResourceBundle bundle = null;
		try {
			bundle = ResourceBundle.getBundle(this.bundle, this.locale);
		} catch (Exception e) {

		}
		ArgPattern argPattern = new ArgPattern();

		String formValidatorName = this
				.getFormValidatorName(validatorResources);
		if (null == formValidatorName) {
			return new SimpleFormValidator(validatorResources, bundle,
					argInjectorFactory, argPattern);
		} else {
			return (FormValidator) Class
					.forName(formValidatorName)
					.getDeclaredConstructor(WebValidateResources.class,
							ResourceBundle.class, ArgInjectorFactory.class,
							ArgPattern.class)
					.newInstance(validatorResources, bundle,
							argInjectorFactory, argPattern);
		}
	}

	public String getFormValidatorName(WebValidateResources validatorResources) {
		String formValidatorName = (String) validatorResources.getConstants()
				.get(FORM_VALIDATOR);
		if (null != formValidatorName && formValidatorName.length() > 0) {
			return formValidatorName;
		}
		return null;
	}
}
